
package auctionServer;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import common.AuctionEvent;
import common.BidEvent;
import common.rmi.RemoteAnalyzer;
import common.rmi.RemoteBillingServer;
import common.rmi.RemoteBillingServerSecure;

import auctionServer.utilities.*;



public class Notifier implements Runnable{
	
	private Vector<Auction> auctions;
	private Timer timer;
	private RemoteAnalyzer analyticsServer;
	private RemoteBillingServer billingServer;
	private String analyticsServerBindingName;
	private String billingServerBindingName;
	//private UDPConnection udpConnection;
	
	public Notifier(Vector<Auction> auctions,String analyticsServerBindingName,String billingServerBindingName){
		this.auctions=auctions;
		this.analyticsServerBindingName=analyticsServerBindingName;
		this.billingServerBindingName=billingServerBindingName;
	}
	
	@Override
	public void run() {
		timer=new Timer();
		String registryHost = "";
		String registryPort = "";
		
		java.io.InputStream is = ClassLoader.getSystemResourceAsStream("registry.properties");
		if (is != null) 
		{
			java.util.Properties props = new java.util.Properties();
			try 
			{
				props.load(is);
				registryHost = props.getProperty("registry.host");
				registryPort = props.getProperty("registry.port");
								
				is.close();
			}
			catch (Exception e) {
				System.out.println(e.getMessage());
			}
		}
		else 
		{
			System.out.println("Properties file not found!");
		}

		String addressRMI = "rmi://" + registryHost + ":" + registryPort + "/";
		
		try {
			analyticsServer=(RemoteAnalyzer)Naming.lookup(addressRMI + analyticsServerBindingName);
			billingServer=(RemoteBillingServer)Naming.lookup(addressRMI + billingServerBindingName);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			System.out.println("Error in connecting to other servers");
		} catch (NotBoundException e) {
			System.out.println("Cannot connect to other servers");
		}
		
		timer.schedule( new TimerTask() {
		    public void run() {
		    	sendOverbidNotifications();
		    	sendEndNotifications();
		   
		    }
		 }, 0, 1*1000);

	}
	private synchronized void sendEndNotifications(){
		for(Auction auction:auctions){
			if(auction.expired()&&auction.getNotificationSent()==false){

				String winner=auction.getWinningBidder();
				if(winner.equals("none")){
					try {
						analyticsServer.processEvent(new AuctionEvent((long)auction.getId(), "AUCTION_ENDED"));
						auction.setNotificationSent(true);
					} catch (RemoteException e) {
						System.out.println("Connection error to analyticsServer");
					}
				}else{
					try {
						analyticsServer.processEvent(new AuctionEvent((long)auction.getId(), "AUCTION_ENDED"));
						analyticsServer.processEvent(new BidEvent("BID_WON",winner,(long)auction.getId(),(double)auction.getCurrentPrice()));
						auction.setNotificationSent(true);
					} catch (RemoteException e) {
						System.out.println("Connection error to analyticsServer");
					}
					
					try {
						RemoteBillingServerSecure billingServerSecure = billingServer.login("auctionClientUser", "dslab2012");
						billingServerSecure.billAuction(winner, auction.getId(), (double)auction.getCurrentPrice());
					} catch (RemoteException e) {
						System.out.println("Connection error to BillingServer");
					}
				}
				for(GroupBid groupBid: Server.groupBids){
					if (groupBid.getAuctionID() == auction.getId())
						groupBid.setIsBidDone(true);
				}
			}
		}
	}
	private synchronized void sendOverbidNotifications(){

		for(Auction auction:auctions){
			if(auction.getJustLost()!=null){
				if(auction.getJustLost().getNotificationSent()==false){
					Bidder overBidded=auction.getJustLost();
					
					try {
						analyticsServer.processEvent(new BidEvent("BID_OVERBID",overBidded.getName(),(long)auction.getId(),(double)overBidded.getAmount()));
						overBidded.setNotificationSent(true);
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}
			}
		}
	}
	public void close(){
		timer.cancel();
		//udpConnection.close();
	}
}


